/**
 * Created by AMD on 29.10.14.
 */
package view {

import InterfaceObjects.ShopObjectContextMenu;
import InterfaceObjects.WallObjectContextMenu;

import ShopObjects.AbstractShelfView;
import ShopObjects.DoorView;

import com.greensock.TweenMax;

import flash.display.Stage;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Point;

import layers.GameLayer;
import layers.InterfaceLayer;

import messages.DebugMessage;

import messages.ModelToViewMessage;
import messages.ViewToControllerMessage;

import model.Constants;

import model.MainProxy;
import model.objects.ProductData;
import model.objects.ShopObjectData;

import mvcexpress.mvc.Mediator;

import starling.display.Image;
import starling.display.QuadBatch;
import starling.events.EnterFrameEvent;

import starling.events.Event;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.filters.ColorMatrixFilter;

public class MainMediator extends Mediator{
    [Inject]
    public var starlingMain:StarlingMain;

    private var _gameLayer:GameLayer;
    private var _interfaceLayer:InterfaceLayer;

    private var _nativeStage:Stage;

    private var _shopObjectContextMenu:ShopObjectContextMenu;
    private var _shopObjectContextMenus:Vector.<ShopObjectContextMenu> = new <ShopObjectContextMenu>[];
    private var _wallObjectContextMenu:WallObjectContextMenu;

    private var _floorMatrix:Matrix;
    private var _wallMatrix:Matrix;

    private var _greenFilter:ColorMatrixFilter = new ColorMatrixFilter();
    private var _redFilter:ColorMatrixFilter = new ColorMatrixFilter();
    override protected function onRegister():void {
        this._nativeStage = starlingMain.nativeStage;

        this._gameLayer = starlingMain.gameLayer;
        mediatorMap.mediate(this._gameLayer);

        this._interfaceLayer = starlingMain.interfaceLayer;
        mediatorMap.mediate(this._interfaceLayer);


        addHandler(ModelToViewMessage.MODE_CHANGED, HANDLER_modeChanged);


        this._shopObjectContextMenu = new ShopObjectContextMenu();//this._contextMenu.alpha = 0.5;
        this._shopObjectContextMenu.addEventListener(ShopObjectContextMenu.EVENT_CONTEXT_BUTTON_TRIGGERED, HANDLER_contextMenuButtonTriggered);
        this._shopObjectContextMenus.push(this._shopObjectContextMenu);

        this._shopObjectContextMenu = new ShopObjectContextMenu();
        this._shopObjectContextMenu.addEventListener(ShopObjectContextMenu.EVENT_CONTEXT_BUTTON_TRIGGERED, HANDLER_contextMenuButtonTriggered);
        this._shopObjectContextMenus.push(this._shopObjectContextMenu);
        addHandler(ModelToViewMessage.CONTEXT_MENU_SO_NEW_TARGET, HANDLER_contextMenuNewTarget);

        this._wallObjectContextMenu = new WallObjectContextMenu();
        this._wallObjectContextMenu.addEventListener(WallObjectContextMenu.EVENT_CONTEXT_BUTTON_TRIGGERED, HANDLER_contextMenuButtonTriggered);
        addHandler(ModelToViewMessage.CONTEXT_MENU_WO_NEW_TARGET, HANDLER_wallObjectContextMenuTargetChanged);

        if(this._wallMatrix == null){
            this._wallMatrix = new Matrix();
            this._wallMatrix.b = 0.5;
        }
        if(this._floorMatrix == null){
            this._floorMatrix = new Matrix();
            this._floorMatrix.rotate(Math.PI/4)
            this._floorMatrix.scale(1,0.5);
        }

        this._greenFilter.tint(0x00ff00,0.8);
        this._redFilter.tint(0xff0000,0.8);
    }

    private function HANDLER_wallObjectContextMenuTargetChanged(data:Object):void {
        if(data != null){
            this._bufPoint = this._interfaceLayer.globalToLocal(this._gameLayer.localToGlobal(this._gameLayer.getLocalCoordsByQuadrant(data.quad)));
            this._showWallObjectContexMenu(this._bufPoint);
        } else {
            this._wallObjectContextMenu.animateDisappearing();
        }
    }
    private function HANDLER_contextMenuNewTarget(data:Object):void {
        var i:int = 0;
        if(data.target == null){
            for (i = 0; i < _shopObjectContextMenus.length; i++) {
                if(_shopObjectContextMenus[i].deployed){
                    _shopObjectContextMenus[i].animateDisappearing();
                }
            }
           // this._contextMenu.animateDisappearing();
        } else {
            this._bufPoint = this._interfaceLayer.globalToLocal(this._gameLayer.localToGlobal(this._gameLayer.getLocalCoordsByQuadrant((data.target as ShopObjectData).position)))

            if(this._shopObjectContextMenu !=null){
                this._shopObjectContextMenu.animateDisappearing();
            }
            this._showNextContexMenu(this._bufPoint);
            /*
            TweenMax.killDelayedCallsTo(this._showContexMenu);
            if(this._contextMenu.deployed){
                this._contextMenu.animateDisappearing();
                TweenMax.delayedCall(0.2, this._showContexMenu, [this._bufPoint.clone()]);
            } else {
                this._showContexMenu(this._bufPoint);
            }
            */
        }
    }
    private function _showNextContexMenu(position:Point):void {
        var i:int = 0;
        for (i = 0; i < this._shopObjectContextMenus.length; i++) {
            if(this._shopObjectContextMenus[i] != this._shopObjectContextMenu){
                this._shopObjectContextMenu = _shopObjectContextMenus[i];
                break;
            }
        }
        this._shopObjectContextMenu.position = position;
        this._shopObjectContextMenu.animateAppearing();
        this._interfaceLayer.addChildAt(this._shopObjectContextMenu,0);
    }

    private function _showWallObjectContexMenu(position:Point):void {
        this._wallObjectContextMenu.position = position;
        this._wallObjectContextMenu.animateAppearing();
        this._interfaceLayer.addChildAt(this._wallObjectContextMenu,0);
    }
    private function HANDLER_contextMenuButtonTriggered(event:Event):void {
        sendMessage(ViewToControllerMessage.INTERFACE_LAYER_TOUCH, {type:event.data.type});
    }


    private var _productIconFollowing:Image;
    private var _productDataBuf:ProductData;
    private var _floorIconFollowing:Image
    private var _wallIconFollowing:Image;
    private var _followingQuad:QuadBatch = new QuadBatch();
    private var _followingWallObjectQuad:QuadBatch = new QuadBatch();
    private var _followingShelf:AbstractShelfView;
    private var _followingDoorView:DoorView;


    private var _bufShopObjectData:ShopObjectData;
    private var _cachedModeParams:Object = null;
    private function HANDLER_modeChanged(params:Object):void {
        switch (params.mode){
            case Constants.MODE_SIMULATION:
            case Constants.MODE_INTERIOR:
                if(params.mode_old == Constants.MODE_SIMULATION_PLACE_PRODUCT){
                    this._productIconFollowing.removeFromParent(true);
                    this._gameLayer.removeEventListener(EnterFrameEvent.ENTER_FRAME, HANDLER_moveProductIcon);
                }else if (params.mode_old == Constants.MODE_INTERIOR_PLACE_FLOOR){
                    this._floorIconFollowing.removeFromParent(true);
                    this._gameLayer.removeEventListener(EnterFrameEvent.ENTER_FRAME, HANDLER_moveFloorIcon);
                }else if (params.mode_old == Constants.MODE_INTERIOR_PLACE_WALL){
                    this._followingQuad.reset()
                    this._followingQuad.removeFromParent(true);
                    this._gameLayer.removeEventListener(EnterFrameEvent.ENTER_FRAME, HANDLER_moveWallIcon);
                } else if(params.mode_old == Constants.MODE_INTERIOR_PLACE_SHELF || params.mode_old == Constants.MODE_INTERIOR_MOVE_SHELF){
                    if(this._followingShelf != null){
                        this._gameLayer.removeEventListener(TouchEvent.TOUCH, HANDLER_moveFollowingShelf);
                        this._followingShelf.removeFromParent(true);
                        //this._followingShelf = null;
                    }
                } else if(String(params.mode_old).indexOf("WALL_COVER") >= 0){
                    this._followingWallObjectQuad.reset();
                    this._followingWallObjectQuad.removeFromParent();
                    this._gameLayer.removeEventListener(TouchEvent.TOUCH, HANDLER_moveFollowingWallObject);
                } else if(String(params.mode_old).indexOf("DOOR") >= 0){
                    this._followingDoorView.removeFromParent();
                    this._gameLayer.removeEventListener(TouchEvent.TOUCH, HANDLER_moveFollowingDoor);
                }
                break;
            case Constants.MODE_SIMULATION_PLACE_PRODUCT:
                this._productDataBuf = ProductData(params.mode_params.product);
                if(this._productDataBuf != null){
                    this._productIconFollowing = GraphicFactory.getImageByName(Constants.PATH_PRODUCT_ICONS_SPRITES+"/icon_"+this._productDataBuf.proto.spriteId);
                    this._interfaceLayer.addChild(this._productIconFollowing);
                    this._productIconFollowing.x = (params.mode_params.position as Point).x + 50;
                    this._productIconFollowing.y = (params.mode_params.position as Point).y;
                    this._gameLayer.addEventListener(EnterFrameEvent.ENTER_FRAME, HANDLER_moveProductIcon);
                }
                break;
            case Constants.MODE_INTERIOR_PLACE_FLOOR:
                    if(params.mode_params.full_sprite_name != null){
                        if(this._floorIconFollowing != null){
                            if(this._floorIconFollowing.parent){
                                this._floorIconFollowing.removeFromParent(true);
                                this._gameLayer.removeEventListener(TouchEvent.TOUCH, HANDLER_moveFloorIcon);
                            }
                            this._floorIconFollowing = null;
                        }
                        this._floorIconFollowing = GraphicFactory.getImageByName(params.mode_params.full_sprite_name);

                        this._floorIconFollowing.transformationMatrix = this._floorMatrix;
                        this._floorIconFollowing.alignPivot();
                        this._floorIconFollowing.alpha = 0.5;

                        this._floorIconFollowing.touchable = false;
                        this._gameLayer.addChild(this._floorIconFollowing);
                        this._gameLayer.addEventListener(TouchEvent.TOUCH, HANDLER_moveFloorIcon);
                    } else {
                        sendMessage(DebugMessage.ERROR_MESSAGE, "MainMediator.as: [mode_params.full_sprite_name] is null! (mode = MODE_PLACE_FLOOR)");
                    }
                break;
            case Constants.MODE_INTERIOR_PLACE_WALL:
                    if(params.mode_params.full_sprite_name != null){
                        if(params.mode_params.full_sprite_name != null){
                            if(this._followingQuad != null){
                                this._followingQuad.reset();
                                if(this._wallIconFollowing){
                                    this._wallIconFollowing.removeFromParent(true);
                                }
                                this._gameLayer.removeEventListener(TouchEvent.TOUCH, HANDLER_moveWallIcon);
                                this._wallIconFollowing = null;
                            }
                            this._wallIconFollowing = GraphicFactory.getImageByName(params.mode_params.full_sprite_name);
                        }

                        this._wallIconFollowing.transformationMatrix = this._wallMatrix;
                        this._wallIconFollowing.alignPivot("left","bottom");
                        this._wallIconFollowing.alpha = 0.9;

                        this._wallIconFollowing.x -= 75;

                        this._followingQuad.reset();
                        this._followingQuad.addImage(this._wallIconFollowing);
                        this._followingQuad.touchable = false;

                        this._wallIconFollowing.touchable = false;
                        this._gameLayer.addChild(this._followingQuad);
                        this._gameLayer.addEventListener(TouchEvent.TOUCH, HANDLER_moveWallIcon);
                    } else {
                        sendMessage(DebugMessage.ERROR_MESSAGE, "MainMediator.as: [mode_params.full_sprite_name] is null! (mode = MODE_PLACE_WALL)");
                    }
                break;
            case Constants.MODE_INTERIOR_MOVE_SHELF:
            case Constants.MODE_INTERIOR_PLACE_SHELF:
                if(params.mode_params.object != null){
                    if(this._followingShelf != null){
                        this._followingShelf.removeFromParent(true);
                        this._gameLayer.removeEventListener(TouchEvent.TOUCH, HANDLER_moveFollowingShelf);
                        //this._followingShelf = null;
                    }
                    this._bufShopObjectData = (params.mode_params.object as ShopObjectData)
                    this._followingShelf = GraphicFactory.createShelfView(String(this._bufShopObjectData.proto.typemodel).split("_")[1]);
                    this._followingShelf.angle = this._bufShopObjectData.angle;
                    this._gameLayer.addChild(this._followingShelf);
                    this._gameLayer.addEventListener(TouchEvent.TOUCH, HANDLER_moveFollowingShelf);

                } else {
                    sendMessage(DebugMessage.ERROR_MESSAGE, "MainMediator.as: [mode_params.object] is null! (mode = [MODE_INTERIOR_PLACE_SHELF or MODE_INTERIOR_MOVE_SHELF])");
                }
                break;
            case Constants.MODE_INTERIOR_MOVE_WALL_COVER:
            case Constants.MODE_INTERIOR_PLACE_WALL_COVER:
                    if(params.mode_params.object != null && params.mode_params.object.full_sprite_name != null){
                        if(this._followingWallObjectQuad != null){
                            this._followingWallObjectQuad.reset();
                            this._gameLayer.removeEventListener(TouchEvent.TOUCH, HANDLER_moveFollowingWallObject);
                        }
                        this._bufPoint.copyFrom(Point(params.mode_params.object.quad));
                        this._cachedModeParams = params.mode_params;

                        this._followingWallObjectQuad.addImage(GraphicFactory.getImageForRender(params.mode_params.object.full_sprite_name));
                        this._followingWallObjectQuad.alpha = 0.7;
                        this._followingWallObjectQuad.scaleX = 1.118033988749895;
                        HANDLER_moveFollowingWallObject(null);
                        this._gameLayer.addEventListener(TouchEvent.TOUCH, HANDLER_moveFollowingWallObject);
                        this._gameLayer.addChild(this._followingWallObjectQuad);
                    }
                break;
            case Constants.MODE_INTERIOR_MOVE_DOOR:
            case Constants.MODE_INTERIOR_MOVE_DOOR:
                if(params.mode_params.object != null && params.mode_params.object.full_sprite_name != null){
                    if(this._followingDoorView != null){
                        this._followingDoorView.removeFromParent();
                        this._gameLayer.removeEventListener(TouchEvent.TOUCH, HANDLER_moveFollowingDoor);
                        this._followingDoorView = null;
                    }
                    this._bufPoint.copyFrom(Point(params.mode_params.object.quad));
                    this._cachedModeParams = params.mode_params;

                    this._followingDoorView = new DoorView(params.mode_params.object.full_sprite_name);
                    this._followingDoorView.touchable = false;

                    HANDLER_moveFollowingDoor(null);
                    this._gameLayer.addEventListener(TouchEvent.TOUCH, HANDLER_moveFollowingDoor);
                    this._gameLayer.addChild(this._followingDoorView);
                }
                break;
        }
    }

    private const _cellConvertedHalfWidth:Number = 100*Math.cos(Math.PI/4);
    private const _cellConvertedHalfHeight:Number = 0.5*100*Math.sin(Math.PI/4);

    private function HANDLER_moveFollowingDoor(event:TouchEvent):void {
        this._mouseToLocalCoords(this._bufQuadrant,this._bufPoint);

        this._followingDoorView.filter = this._redFilter;
        if(this._bufQuadrant.y == -1 && this._bufQuadrant.x >=0){
            this._followingDoorView.angle = 225;
            this._wallObjectOffsetX = - _cellConvertedHalfWidth;
            this._wallObjectOffsetY =  _cellConvertedHalfHeight;

            if(this._bufQuadrant.x != 0) this._followingDoorView.filter = this._greenFilter;//(0,0) is deprecated !!!

            this._bufVectorString = this._cachedModeParams.wall_covers.x;
            this._bufInt = this._bufQuadrant.x
            if(_bufVectorString.length <= this._bufInt || this._bufVectorString[this._bufInt] != null){
                this._followingDoorView.filter = this._redFilter;
            };
            this._bufVectorString = this._cachedModeParams.doors.x;
            if(_bufVectorString.length <= this._bufInt || this._bufVectorString[this._bufInt] != null){
                this._followingDoorView.filter = this._redFilter;
            };
        } else if(this._bufQuadrant.x == -1 && this._bufQuadrant.y >=0){//(0,0) is deprecated !!!
            this._followingDoorView.angle = 135;
            this._wallObjectOffsetX = _cellConvertedHalfWidth;
            this._wallObjectOffsetY = _cellConvertedHalfHeight;

            if(this._bufQuadrant.y != 0) this._followingDoorView.filter = this._greenFilter;//(0,0) is deprecated !!!

            this._bufVectorString = this._cachedModeParams.wall_covers.y;
            this._bufInt = this._bufQuadrant.y
            if(_bufVectorString.length <= this._bufInt || this._bufVectorString[this._bufInt] != null){
                this._followingDoorView.filter = this._redFilter;
            };
            this._bufVectorString = this._cachedModeParams.doors.y;
            if(_bufVectorString.length <= this._bufInt || this._bufVectorString[this._bufInt] != null){
                this._followingDoorView.filter = this._redFilter;
            };
        }
        this._followingDoorView.x = this._bufPoint.x + this._wallObjectOffsetX;
        this._followingDoorView.y = this._bufPoint.y + this._wallObjectOffsetY;
    }


    private var _wallObjectOffsetX:int = 0;
    private var _wallObjectOffsetY:int = 0;
    private var _bufVectorString:Vector.<String> = null;
    private var _bufInt:int = 0;
    private function HANDLER_moveFollowingWallObject(event:TouchEvent):void {
        this._mouseToLocalCoords(this._bufQuadrant,this._bufPoint);

        this._followingWallObjectQuad.x = this._bufPoint.x + this._wallObjectOffsetX;
        this._followingWallObjectQuad.y = this._bufPoint.y + this._wallObjectOffsetY;

        this._followingWallObjectQuad.filter = this._redFilter;
        if(this._bufQuadrant.y == -1 && this._bufQuadrant.x >=0){
            this._wallObjectOffsetX = - _cellConvertedHalfWidth;
            this._wallObjectOffsetY = 0;
            this._followingWallObjectQuad.skewY = 0.46364760900080615;
            this._followingWallObjectQuad.filter = this._greenFilter;

            this._bufVectorString = this._cachedModeParams.wall_covers.x;
            this._bufInt = this._bufQuadrant.x
            if(_bufVectorString.length <= this._bufInt || this._bufVectorString[this._bufInt] != null){
                this._followingWallObjectQuad.filter = this._redFilter;
            };
            this._bufVectorString = this._cachedModeParams.doors.x;
            if(_bufVectorString.length <= this._bufInt || this._bufVectorString[this._bufInt] != null){
                this._followingWallObjectQuad.filter = this._redFilter;
            };
        } else if(this._bufQuadrant.x == -1 && this._bufQuadrant.y >=0){
            this._wallObjectOffsetX = 0;
            this._wallObjectOffsetY = _cellConvertedHalfHeight;
            this._followingWallObjectQuad.skewY = -0.46364760900080615;
            this._followingWallObjectQuad.filter = this._greenFilter;

            this._bufVectorString = this._cachedModeParams.wall_covers.y;
            this._bufInt = this._bufQuadrant.y
            if(_bufVectorString.length <= this._bufInt || this._bufVectorString[this._bufInt] != null){
                this._followingWallObjectQuad.filter = this._redFilter;
            };
            this._bufVectorString = this._cachedModeParams.doors.y;
            if(_bufVectorString.length <= this._bufInt || this._bufVectorString[this._bufInt] != null){
                this._followingWallObjectQuad.filter = this._redFilter;
            };
        }
    }




    private function HANDLER_moveFollowingShelf(event:TouchEvent):void {
        this._mouseToLocalCoords(this._bufQuadrant,this._bufPoint);

        //TODO: highlight occ_points

        this._followingShelf.x = this._bufPoint.x ;
        this._followingShelf.y = this._bufPoint.y ;
    }



    private var _bufPoint:Point = new Point();
    private function HANDLER_moveFloorIcon(event:TouchEvent):void {
        this._mouseToLocalCoords(this._bufQuadrant,this._bufPoint);

        this._floorIconFollowing.x = this._bufPoint.x;
        this._floorIconFollowing.y = this._bufPoint.y;
    }
    private var _bufQuadrant:Point = new Point();
    private function HANDLER_moveWallIcon(event:TouchEvent):void {
        this._mouseToLocalCoords(this._bufQuadrant,this._bufPoint);

        if(this._bufQuadrant.y == -1 && this._bufQuadrant.x >=0){
            this._followingQuad.scaleX = 1;
        } else if(this._bufQuadrant.x == -1 && this._bufQuadrant.y >=0){
            this._followingQuad.scaleX = -1;
        }
        this._followingQuad.x = this._bufPoint.x;
        this._followingQuad.y = this._bufPoint.y;

        //this._wallIconFollowing.scaleX = -1.5;
    }

    private function _mouseToLocalCoords(resultQuadrant:Point,resultCoords:Point):void {
        this._bufPoint.setTo(this._nativeStage.mouseX,this._nativeStage.mouseY);
        this._bufPoint.copyFrom(this._gameLayer.shopView.getQuadrant(this._bufPoint));
        resultQuadrant.copyFrom(this._bufPoint);
        resultCoords.copyFrom(this._gameLayer.getLocalCoordsByQuadrant(this._bufPoint));
    }

    private var _bufEvent:EnterFrameEvent = null;
    private function HANDLER_moveProductIcon(event:EnterFrameEvent):void {
        this._productIconFollowing.x = this._nativeStage.mouseX + 50;
        this._productIconFollowing.y = this._nativeStage.mouseY;
    }


    override protected function onRemove():void {

    }


}
}
